#include "app_device.h"
#include "log.h"
#include "gpio.h"
#include "timer.h"
//#include "iwdg.h"
#include "data.h"
#include "mlx90614.h"
#include "mpu6050.h"
#include "math.h"
#include "app_audio.h"
#include "app_msg.h"

static u8 beep_count = 0;
static u8 mpu_alarm_temp = 1;

int beep_binker_Stop(void)
{
  timer_stop(TIMER_BEEP_LOOP);
  BEEP_ON;
  beep_count = 0;
  data_getData()->MPU_ALARM_FLAG = 0;
  data_getData()->HEART_ALARM_FLAG = 0;
  data_getData()->TEMP_ALARM_FLAG = 0;
  data_getData()->PRES_ALARM_FLAG = 0;
}
void beep_binker_Handler(void)
{
  if(data_getData()->MPU_ALARM_FLAG != 0 && mpu_alarm_temp)
  {
    mpu_alarm_temp = 0;
    WIFI_Send_AlarmInfoHandler();
  }
  if(beep_count++ >15)   //报警持续时间这设置5秒
  {
    mpu_alarm_temp = 1;
    beep_binker_Stop();
    return;
  }
  BEEP_TURN;
  timer_start(TIMER_BEEP_LOOP, TIMER_100MS*3+30, beep_binker_Handler);
}

void led2_off(void)
{
  LED_2_OFF;
}

void data_upload_Handler(void)
{
  LED_2_ON;
  WIFI_TIMER_HANDER();
  timer_start(TIMER_LED2_OFF_LOOP, TIMER_S*1, led2_off);
  timer_start(TIMER_UPDTA_LOOP, TIMER_S*5, data_upload_Handler);
}

int timer_1s_Handler(void)
{
  STM_DATA *pData = data_getData();

  LED_1_TURN;
  
  pData->temperature_temp = SMBus_ReadTemp(); //实际温度获取
  if(pData->temp_mode)//测温模式
  {
    if(pData->temperature_temp > pData->temperature_max)
    {
      pData->temperature_max = pData->temperature_temp;
    }
    pData->temperature = pData->temperature_max + pData->temp_compensate;
  }
  else//后台测温模式，不适用最大值
  {
    pData->temperature = pData->temperature_temp + pData->temp_compensate;
  }
  
  //血压测量
  data_getData()->pressure = Get_Pressure();
  
  //温度报警判断
  if(pData->temperature > pData->Alarm_Line[2])
  {
    beep_count = 0;
    data_getData()->TEMP_ALARM_FLAG = 1;
    beep_binker_Handler();
    audio_play(3,10);
    WIFI_Send_AlarmInfoHandler();
  }
  
  //心率报警判断
  if(pData->heart > pData->Alarm_Line[1])
  {
    beep_count = 0;
    data_getData()->HEART_ALARM_FLAG = 1;
    beep_binker_Handler();
    audio_play(4,10);
    WIFI_Send_AlarmInfoHandler();
  }
  
  //printf("press %0.0f | temp %0.2f | heart %d | spo2 %d\r\n",pData->pressure,pData->temperature,pData->heart,pData->spo2);
  //printf("pitch %0.1f | roll %0.1f | yaw %0.1f | SVM %d\r\n\n",fabs(pData->pitch),fabs(pData->roll),fabs(pData->yaw),pData->SVM);
  timer_start(TIMER_1S_LOOP, TIMER_S*1, timer_1s_Handler);
  
  return 0;
}

int led_binker_Handler(void)
{
  LED_S_TURN;
//  HAL_IWDG_Refresh(&hiwdg);
  timer_start(TIMER_LED_LOOP, TIMER_100MS, led_binker_Handler);
  return 0;
}

void max_timer_clean(void)
{
  data_getData()->heart = 0;
  data_getData()->spo2 = 0;
  LOG_DEBUG("MAX30102 clean heart and sop2!!");
}

void dect_down(void)
{
  u8 mpu_flag = 0;      	//人体跌倒检测标志位 标志位1、2任意一个异常 该标志位为1 	【1：跌倒，0：正常】
  _Bool mpu_1_flag = 0;   //人体跌倒检测标志位1	角度异常标志		【1：异常，0：正常】
  _Bool mpu_2_flag = 0;   //人体跌倒检测标志位2	加速度异常标志	【1：异常，0：正常】
  int SVM;								//人体加速度向量幅值SVM和微分加速度幅值的绝对平均值DSVM是区分人体运动状态的重要参量。SVM通过计算加速度幅度表征人体运动的剧烈程度，其值越大表明运动越剧烈。
	float pitch,roll,yaw; 	//欧拉角
	short aacx,aacy,aacz;		//加速度传感器原始数据

  //====MPU6050数据获取====
  if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)
  { 
    MPU_Get_Accelerometer(&aacx,&aacy,&aacz);	//得到加速度传感器数据		
    SVM = sqrt(pow(aacx,2)+  pow(aacy,2) + pow(aacz,2));	
    
    //分析x、y、z角度的异常判断
    if( fabs(pitch)>data_getData()->Alarm_Line[0] 
      || fabs(roll)>data_getData()->Alarm_Line[0] 
      || fabs(yaw) >data_getData()->Alarm_Line[0]  )//倾斜角度的 【绝对值】 大于40°SVM大于设定的阈值时，即认为摔倒
      mpu_1_flag = 1;	
    else
      mpu_1_flag = 0;
    //分析加速度SVM的异常判断
    if( SVM>25000 || SVM<9000 )
      mpu_2_flag = 1;
    else
      mpu_2_flag = 0;
    //综合欧拉角、SVM异常判断异常	
    if( mpu_2_flag || mpu_1_flag )
    {
      mpu_flag = 1;
      beep_count = 0;
      data_getData()->MPU_ALARM_FLAG = 1;
      beep_binker_Handler();
      audio_play(6,10);
    }
    
    data_getData()->pitch = fabs(pitch);
    data_getData()->roll = fabs(roll);
    data_getData()->yaw = fabs(yaw);
    data_getData()->SVM = SVM;			
  }
}



